#include <vector>
using namespace std;
#include <set>
#include <algorithm>


// version 1 
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> ret = {-1, -1};
        if(nums.empty()) return ret;

        int left = 0, right = nums.size() - 1;
        while(left <= right && (nums[left] != nums[right] || (nums[left] == nums[right] && nums[left] != target))){
            int mid = left + (right - left) / 2;
            if(nums[mid] < target) left = ++mid;
            else if(nums[mid] > target) right = --mid;
            else {
                if(nums[left] != target) ++left;
                if(nums[right] != target) --right;
            }
        }

        if (left > right) return ret;

        ret[0] = left;
        ret[1] = right;
        return ret;
    }
};

/* 自己写的版本 但是判断逻辑很复杂 */







//version 2
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> ret = {-1, -1};
        if(nums.size() == 0) return ret;
        
        int left = 0, right = nums.size() - 1;
        //这里采用查找左右端点的办法

        //1.查找左端点
        while(left < right){
            int mid = left + (right - left) / 2;
            if(nums[mid] < target) left = ++mid;
            else right = mid;
        }
        //出循环一定是left = right
        if(nums[left] == target) ret[0] = left;
        else return ret; //左端点都没找到 -> 一个数字都没有 -> 不用继续判断了

        //2.查找右端点
        left = 0, right = nums.size() - 1;
        while(left < right){
            int mid = left + (right - left + 1) / 2;
            if(nums[mid] > target) right = --mid;
            else left = mid;
        }
        //出循环一定是left = right
        if(nums[right] == target) ret[1] = right;

        return ret;
    }
};  

/* 这个是使用二分查找的基本思想——区分二段性
分别查找左右端点即可，但是需要注意很多的细节 */

